using System;
using System.Runtime.Serialization;

namespace BanZuiCloudControlAgent.Utils.Exceptions
{
    /// <summary>
    /// QQ自动化相关异常类，用于表示QQ操作、自动化等过程中发生的错误
    /// </summary>
    [Serializable]
    public class QQException : BanZuiException
    {
        /// <summary>
        /// QQ错误类型
        /// </summary>
        public QQErrorType ErrorType { get; }

        /// <summary>
        /// QQ账号（如果适用）
        /// </summary>
        public string QQAccount { get; }

        /// <summary>
        /// 初始化QQException类的新实例
        /// </summary>
        public QQException() : base("E300", "QQ", "QQ操作发生错误")
        {
            ErrorType = QQErrorType.Unknown;
            QQAccount = null;
        }

        /// <summary>
        /// 使用指定的错误消息初始化QQException类的新实例
        /// </summary>
        /// <param name="message">描述错误的消息</param>
        public QQException(string message) : base("E300", "QQ", message)
        {
            ErrorType = QQErrorType.Unknown;
            QQAccount = null;
        }

        /// <summary>
        /// 使用指定的错误消息和内部异常初始化QQException类的新实例
        /// </summary>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public QQException(string message, Exception innerException) : base("E300", "QQ", message, false, innerException)
        {
            ErrorType = QQErrorType.Unknown;
            QQAccount = null;
        }

        /// <summary>
        /// 使用指定的错误类型和消息初始化QQException类的新实例
        /// </summary>
        /// <param name="errorType">QQ错误类型</param>
        /// <param name="message">描述错误的消息</param>
        public QQException(QQErrorType errorType, string message) : base(GetErrorCode(errorType), "QQ", message)
        {
            ErrorType = errorType;
            QQAccount = null;
        }

        /// <summary>
        /// 使用指定的错误类型、消息和内部异常初始化QQException类的新实例
        /// </summary>
        /// <param name="errorType">QQ错误类型</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public QQException(QQErrorType errorType, string message, Exception innerException) : base(GetErrorCode(errorType), "QQ", message, false, innerException)
        {
            ErrorType = errorType;
            QQAccount = null;
        }

        /// <summary>
        /// 使用指定的错误类型、QQ账号和消息初始化QQException类的新实例
        /// </summary>
        /// <param name="errorType">QQ错误类型</param>
        /// <param name="qqAccount">QQ账号</param>
        /// <param name="message">描述错误的消息</param>
        public QQException(QQErrorType errorType, string qqAccount, string message) : base(GetErrorCode(errorType), "QQ", message)
        {
            ErrorType = errorType;
            QQAccount = qqAccount;
        }

        /// <summary>
        /// 使用指定的错误类型、QQ账号、消息和内部异常初始化QQException类的新实例
        /// </summary>
        /// <param name="errorType">QQ错误类型</param>
        /// <param name="qqAccount">QQ账号</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public QQException(QQErrorType errorType, string qqAccount, string message, Exception innerException) : base(GetErrorCode(errorType), "QQ", message, false, innerException)
        {
            ErrorType = errorType;
            QQAccount = qqAccount;
        }

        /// <summary>
        /// 使用序列化数据初始化QQException类的新实例
        /// </summary>
        /// <param name="info">SerializationInfo，它存有关于所引发的异常的序列化的对象数据</param>
        /// <param name="context">包含有关源或目标的上下文信息</param>
        protected QQException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
            ErrorType = (QQErrorType)info.GetInt32("ErrorType");
            QQAccount = info.GetString("QQAccount");
        }

        /// <summary>
        /// 使用可序列化的数据填充SerializationInfo
        /// </summary>
        /// <param name="info">要填充数据的SerializationInfo</param>
        /// <param name="context">此序列化的目标</param>
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
            info.AddValue("ErrorType", (int)ErrorType);
            info.AddValue("QQAccount", QQAccount);
        }

        /// <summary>
        /// 获取包含错误代码、QQ账号的完整错误消息
        /// </summary>
        /// <returns>包含错误代码、QQ账号的完整错误消息</returns>
        public override string ToString()
        {
            if (string.IsNullOrEmpty(QQAccount))
            {
                return base.ToString();
            }
            return $"[{ErrorCode}] {Module} (QQ: {QQAccount}): {Message}";
        }

        /// <summary>
        /// 根据QQ错误类型获取错误代码
        /// </summary>
        /// <param name="errorType">QQ错误类型</param>
        /// <returns>错误代码</returns>
        private static string GetErrorCode(QQErrorType errorType)
        {
            switch (errorType)
            {
                case QQErrorType.LoginFailed:
                    return "E301";
                case QQErrorType.LogoutFailed:
                    return "E302";
                case QQErrorType.SendMessageFailed:
                    return "E303";
                case QQErrorType.JoinGroupFailed:
                    return "E304";
                case QQErrorType.LeaveGroupFailed:
                    return "E305";
                case QQErrorType.AddFriendFailed:
                    return "E306";
                case QQErrorType.ElementNotFound:
                    return "E307";
                case QQErrorType.OperationTimeout:
                    return "E308";
                case QQErrorType.VerificationRequired:
                    return "E309";
                case QQErrorType.AccountBlocked:
                    return "E310";
                default:
                    return "E300";
            }
        }
    }

    /// <summary>
    /// QQ错误类型枚举
    /// </summary>
    public enum QQErrorType
    {
        /// <summary>
        /// 未知错误
        /// </summary>
        Unknown = 0,

        /// <summary>
        /// 登录失败
        /// </summary>
        LoginFailed = 1,

        /// <summary>
        /// 登出失败
        /// </summary>
        LogoutFailed = 2,

        /// <summary>
        /// 发送消息失败
        /// </summary>
        SendMessageFailed = 3,

        /// <summary>
        /// 加入群聊失败
        /// </summary>
        JoinGroupFailed = 4,

        /// <summary>
        /// 退出群聊失败
        /// </summary>
        LeaveGroupFailed = 5,

        /// <summary>
        /// 添加好友失败
        /// </summary>
        AddFriendFailed = 6,

        /// <summary>
        /// 元素未找到
        /// </summary>
        ElementNotFound = 7,

        /// <summary>
        /// 操作超时
        /// </summary>
        OperationTimeout = 8,

        /// <summary>
        /// 需要验证
        /// </summary>
        VerificationRequired = 9,

        /// <summary>
        /// 账号被封禁
        /// </summary>
        AccountBlocked = 10
    }
} 